class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int n = nums.length;
        // 状态表示
        int[] f = new int[n]; // 以第 i 个位置为结尾的子数组的最大和
        int[] g = new int[n]; // 以第 i 个位置为结尾的子数组的最小和
        // 初始化
        f[0] = nums[0];
        g[0] = nums[0];
        // 状态转移方程
        int max = f[0];
        int min = g[0];
        for(int i = 1; i < n; i++){
            f[i] = Math.max(nums[i], f[i - 1] + nums[i]);
            max = Math.max(max, f[i]);
            g[i] = Math.min(nums[i], g[i - 1] + nums[i]);
            min = Math.min(min, g[i]);
        }
        int sum = 0;
        for(int i = 0; i < n; i++) sum += nums[i];
        if(min == sum) return max;
        else return Math.max(max, sum - min);
    }
}